#include "Entity Manager.h"
#include "Collision.h"
#include "GameWorld.h"
#include "GameBoard.h"

/*	-------------------Instance-----------------------------
	This will return a pointer to the Entity Manager.	*/

EntityManager* EntityManager::Instance()
{
	static EntityManager instance;	
	return &instance;
}

//	-------------------GetEntityFromID-------------------------
//	Using the entity ID as an index, it searches through the 
//	EntityMap and returns a pointer the desired entity. If the 
//	desired ID cannot be found, then it creates an assertion 
//	error. 

BaseGameEntity* EntityManager::GetEntityFromID(int id)
{
	// Find the entity 
	EntityMap::const_iterator ent = m_EntityMap.find(id);
	if(!(ent != m_EntityMap.end()))
	assert( (ent != m_EntityMap.end()) && "<EntityManager::GetEntityFromID>: invalid ID");

	return ent -> second;	// It says second because it returns the second value stored at the
							// position pointed to by the iterator ent. That is, in the map of 
							// type <int, Character> it will return the Moving Entity. 
}


//	-----------------------RemoveEntity--------------------------
//	Takes a pointer to the desired entity. Removes the desired
//	entity from m_EntityMap. 

void EntityManager::RemoveEntity(BaseGameEntity* pEntity)
{
	m_EntityMap.erase(m_EntityMap.find(pEntity->ID()));
}

//	----------------------RegisterEntity---------------------------
//	Takes a pointer to the desired entity. Adds it to the EntityMap 
void EntityManager::RegisterEntity(BaseGameEntity* NewEntity)
{
  m_EntityMap.insert(std::make_pair(NewEntity->ID(), NewEntity));
}



bool EntityManager::CheckCollision(int entID1, int entID2)
{
	Vector2D pos1 = GetEntityFromID(entID1)->Pos();
	Vector2D pos2 = GetEntityFromID(entID2)->Pos();

	double cRadius = GetEntityFromID(entID1)->CRadius() + GetEntityFromID(entID2)->CRadius();

	return (Vec2DDistance(pos1, pos2) < cRadius);
}

//	----------------------GetAllEntityPositions---------------------------
//	Returns a vector of coords of all the entities positions
vector<Vector2D> EntityManager::GetAllEntityPositions()
{
	vector<Vector2D> entityPos;

	map<int, BaseGameEntity*>::iterator iter;
	for(iter = m_EntityMap.begin(); iter != m_EntityMap.end(); iter++)
	{
		entityPos.push_back(iter->second->Pos());
	}

	return entityPos;
}

list<BaseGameEntity*> EntityManager::GetCollisions(BaseGameEntity* pEntity)
{
	WorldMap->GetPartition().CalculateCollisions(pEntity);

	list<BaseGameEntity*> aList;
	BaseGameEntity* curEntity = WorldMap->GetPartition().begin();
	while(!(WorldMap->GetPartition().end()))
	{
		aList.push_back(curEntity);
		curEntity = WorldMap->GetPartition().next();
	}

	return aList;
}

list<MovingEntity*> EntityManager::GetNeighbors(BaseGameEntity* pEntity)
{
	WorldMap->GetPartition().CalculateNeighbors(pEntity->Pos(), pEntity->CRadius()*3.0);
	list<MovingEntity*> aList;
	BaseGameEntity* curEntity = WorldMap->GetPartition().begin();
	while(!(WorldMap->GetPartition().end()))
	{
		aList.push_back((MovingEntity*)curEntity);
		curEntity = WorldMap->GetPartition().next();
	}

	return aList;
}